package com.chc.web.user.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chc.config.jwt.JwtUtils;
import com.chc.utils.CommonResult;
import com.chc.web.menu.entity.MakeMenuTree;
import com.chc.web.menu.entity.Menu;
import com.chc.web.menu.entity.RouterVO;
import com.chc.web.menu.service.MenuService;
import com.chc.web.reader.entity.Reader;
import com.chc.web.reader.service.ReaderService;
import com.chc.web.user.entity.*;
import com.chc.web.user.service.UserService;
import com.chc.web.user_role.entity.UserRole;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA
 *
 * @Author: chc
 * @Date: 2021/12/19/21:29
 * @Description:
 */

@RestController
@RequestMapping("/api/user")
public class UserController {

    //注入userService实现类
    @Autowired
    private UserService userService;

    //注入token实现类
    @Autowired
    private JwtUtils jwtUtils;

    @Resource
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private ReaderService readerService;

    @Autowired
    private MenuService menuService;

    /**
     * 组装动态路由
     * */
    @GetMapping("/getMenuList")
    public CommonResult getMenuList(HttpServletRequest request){
        //从头部获取token
        String token = request.getHeader("X-Token");
        Claims claims = jwtUtils.getClaimsFromToken(token);
        //获取用户名
        String username = jwtUtils.getUsernameFromToken(token);
        //获取用户类型
        String userType = (String) claims.get("userType");
        if (userType.equals("0")){ //业主
            //查询业主的权限信息
            Reader reader = readerService.loadUser(username);
            List<Menu> menuList = menuService.getMenuListByUserIdForReader(reader.getId());
            //只需要获取目录和菜单
            List<Menu> collect = menuList.stream().filter(item -> item != null && !item.getType().equals("2")).collect(Collectors.toList());
            //组装路由数据
            List<RouterVO> list = MakeMenuTree.makeRouter(collect,0L);
            return CommonResult.success("查询成功",list);
        }else {
            //查询业主的权限信息
            User user = userService.loadUser(username);
            List<Menu> menuList = menuService.getMenuListByUserId(user.getUserId());
            //只需要获取目录和菜单
            List<Menu> collect = menuList.stream().filter(item -> item != null && !item.getType().equals("2")).collect(Collectors.toList());
            //组装路由数据
            List<RouterVO> list = MakeMenuTree.makeRouter(collect,0L);
            return CommonResult.success("查询成功",list);
        }
    }

    /**
     * 获取用户信息
     * */
    @GetMapping("/getInfo")
    public CommonResult getInfo(User user, HttpServletRequest request){
        //从头部获取token
        String token = request.getHeader("X-Token");
        //获取用户类型
        Claims claims = jwtUtils.getClaimsFromToken(token);
        String userType = (String) claims.get("userType");
        if (userType.equals("0")){ //读者
            //根据id查询该登录用户
            Reader reader = readerService.getById(user.getUserId());
            //用户信息实体类
            UserInfo userInfo = new UserInfo();
            //获取用户id
            userInfo.setId(reader.getId());
            //获取用户姓名
            userInfo.setName(reader.getUsername());
            //获取用户头像
            userInfo.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
            //查询读者权限信息
            List<Menu> menuList = menuService.getMenuListByUserIdForReader(reader.getId());
            //获取权限字段
            List<String> collect = menuList.stream().filter(item -> item != null).map(item -> item.getMenuCode()).filter(item -> item != null).collect(Collectors.toList());
            //转成数组
            String[] strings = collect.toArray(new String[collect.size()]);
            //将权限字段返回给前端
            userInfo.setRoles(strings);
            //返回成功的信息给前端
            return CommonResult.success("获取用户信息成功",userInfo);
        }else{ //管理员
            //根据id查询该登录用户
            User user1 = userService.getById(user.getUserId());
            //用户信息实体类
            UserInfo userInfo = new UserInfo();
            //获取用户id
            userInfo.setId(user1.getUserId());
            //获取用户姓名
            userInfo.setName(user1.getUsername());
            //获取用户头像
            userInfo.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
            //查询管理员权限信息
            List<Menu> menuList = menuService.getMenuListByUserId(user.getUserId());
            //获取权限字段
            List<String> collect = menuList.stream().filter(item -> item != null).map(item -> item.getMenuCode()).filter(item -> item != null).collect(Collectors.toList());
            //转成数组
            String[] strings = collect.toArray(new String[collect.size()]);
            //将权限字段返回给前端
            userInfo.setRoles(strings);
            //返回成功的信息给前端
            return CommonResult.success("获取用户信息成功",userInfo);
        }

    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public CommonResult login(@RequestBody LoginParm parm){
        //判断前端表单传过来的值是否为空
        if(StringUtils.isEmpty(parm.getUsername()) || StringUtils.isEmpty(parm.getPassword()) || StringUtils.isEmpty(parm.getUserType())){
            return CommonResult.error("用户名、密码或用户类型不能为空!");
        }
        //查询用户信息，并对该用户进行md5解密
//        String password = DigestUtils.md5DigestAsHex(parm.getPassword().getBytes());
        String encode = passwordEncoder.encode(parm.getPassword());
        //spring-security需要的token
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(parm.getUsername() + ":" + parm.getUserType(), parm.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authenticate);
        if (parm.getUserType().equals("0")){ //读者
            Reader reader = (Reader) authenticate.getPrincipal();
            //生成token返回给前端
            String token = jwtUtils.generateToken(parm.getUsername(), parm.getUserType());
            //获取生产的token的过期时间
            Long expireTime = jwtUtils.getExpireTime(token, jwtUtils.getSecret());
            LoginResult result = new LoginResult();
            result.setUserId(reader.getId());
            result.setToken(token);
            result.setExpireTime(expireTime);
            return CommonResult.success("登录成功",result);
        }else if (parm.getUserType().equals("1")){ //管理员
            User user = (User) authenticate.getPrincipal();
            //生成token返回给前端
            String token = jwtUtils.generateToken(parm.getUsername(), parm.getUserType());
            //获取生产的token的过期时间
            Long expireTime = jwtUtils.getExpireTime(token, jwtUtils.getSecret());
            LoginResult result = new LoginResult();
            result.setUserId(user.getUserId());
            result.setToken(token);
            result.setExpireTime(expireTime);
            return CommonResult.success("登录成功",result);
        }else{
            return CommonResult.error("您选择的用户类型不存在!");
        }
    }

    //用户退出
    @PostMapping("/loginOut")
    public CommonResult loginOut(HttpServletRequest request, HttpServletResponse response){
        //获取用户相关信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication != null){
            //清空用户信息
            new SecurityContextLogoutHandler().logout(request,response,authentication);

        }
        return CommonResult.success("退出登录成功!");
    }

    //新增员工
    @PostMapping
    public CommonResult addUser(@RequestBody  @Valid User user){
        if(StringUtils.isNotEmpty(user.getUsername())){
            //判断登陆名 的唯一性
            QueryWrapper<User> query = new QueryWrapper<>();
            query.lambda().eq(User::getUsername,user.getUsername());
            User one = userService.getOne(query);
            if (one != null){
                return CommonResult.error("登录名已经被占用!", 500);
            }
        }
        //如果密码存在，加密md5
        if(StringUtils.isNotEmpty(user.getPassword())){
            user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        }
        userService.save(user);
        return CommonResult.success("保存员工成功");
    }


    //编辑员工
    @PutMapping
    public CommonResult editUser(@RequestBody User user){
        if(StringUtils.isNotEmpty(user.getUsername())){
            //判断登陆名 的唯一性
            QueryWrapper<User> query = new QueryWrapper<>();
            query.lambda().eq(User::getUsername,user.getUsername());
            User one = userService.getOne(query);
            if (one != null){
                return CommonResult.error("登录名已经被占用!", 500);
            }
        }
        //如果密码存在，加密md5
        if(StringUtils.isNotEmpty(user.getPassword())){
            user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
        }
        boolean b = userService.updateById(user);
        if (b){
            return CommonResult.success("编辑员工成功");
        }else {
            return CommonResult.error("编辑员工失败");
        }
    }

    //删除员工
    @DeleteMapping("/{userId}")
    public CommonResult deleteUser(@PathVariable("userId") Long userId){
        boolean b = userService.removeById(userId);
        if (b){
            return CommonResult.success("删除员工成功");
        }else {
            return CommonResult.error("删除员工失败");
        }
    }

    //查询用户列表
    @GetMapping("/list")
    public CommonResult list(UserParm parm){
        IPage<User> list = userService.list(parm);
        return CommonResult.success("查询成功",list);
    }

    //根据用户id查询角色id
    @GetMapping("/getRoleByUserId")
    public CommonResult getRoleByUserId(UserRole userRole){
        UserRole userRole1 = userService.getRoleByUserId(userRole);
        return CommonResult.success("查询成功",userRole1);
    }

    //分配角色保存
    @PostMapping("/saveRole")
    public CommonResult saveRole(@RequestBody UserRole userRole){
        userService.saveRole(userRole);
        return CommonResult.success("分配角色成功!");
    }



}
